#include "qlanguagemanager.h"

#include <QVariant>
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>

using namespace SHAREDLIB;

QLanguageManager::QLanguageManager(QObject *parent) :
    QObject(parent),
    m_current(NULL)
{
}

QLanguageManager::~QLanguageManager()
{
    release();
}

void QLanguageManager::addLanguage(QObject *obj)
{
    if(obj==NULL || m_languages.contains(obj))
    {
        return;
    }
    if(m_current==NULL)
    {
        m_current=obj;
    }
    m_languages.append(obj);
    emit languageAdd(obj,-1);
}

void QLanguageManager::insertLanguage(int index, QObject *obj)
{
    if(obj==NULL || m_languages.contains(obj))
    {
        return;
    }
    if(m_current==NULL)
    {
        m_current=obj;
    }
    if(index<0 || index>m_languages.size())
    {
        index=m_languages.size();
    }
    m_languages.insert(index,obj);
    emit languageAdd(obj,index);
}

void QLanguageManager::removeLanguage(const QString &languageName)
{
    foreach(QObject* obj,m_languages)
    {
        if(obj->property("languageName").toString()==languageName)
        {
            foreach(tagLanguageItem *item,m_texts)
            {
                item->m_translate.remove(obj);
            }
            m_languages.removeAll(obj);
            if(obj==m_current)
            {
                setCurrentLanguage(m_languages.size()>0?m_languages.first():NULL);
            }
            emit languageDel(obj);
            delete obj;
            return;
        }
    }
}

QObject* QLanguageManager::getLanguage(const QString &languageName)
{
    foreach(QObject* obj,m_languages)
    {
        if(obj->property("languageName").toString()==languageName)
        {
            return obj;
        }
    }
    return NULL;
}

QObject* QLanguageManager::getLanguage(int index)
{
    if(index<0 || index>=m_languages.size())
    {
        return NULL;
    }
    return m_languages.at(index);
}

int QLanguageManager::languageIndex(QObject *obj)
{
    return m_languages.indexOf(obj);
}

int QLanguageManager::languageCount()
{
    return m_languages.size();
}

QStringList QLanguageManager::languages()
{
    QStringList list;
    foreach(QObject* obj,m_languages)
    {
        list.append(obj->property("languageName").toString());
    }
    return list;
}

void QLanguageManager::swapLanguage(int index1, int index2)
{
    m_languages.swap(index1,index2);
}

void QLanguageManager::setCurrentLanguage(const QString &languageName)
{
    QObject *obj=getLanguage(languageName);
    m_current=obj;
    emit currentLanguageChanged(obj);
}

void QLanguageManager::setCurrentLanguage(QObject *language)
{
    m_current=language;
    emit currentLanguageChanged(language);
}

QObject* QLanguageManager::getCurrentLanguage()
{
    return m_current;
}

QString QLanguageManager::getText(const QString &languageName, const QString &id)
{
    QObject *lan=getLanguage(languageName);
    if(lan==NULL)
    {
        return "";
    }
    foreach(tagLanguageItem *it,m_texts)
    {
        if(it->m_id==id)
        {
            return it->m_translate.value(lan,"");
        }
    }
    return "";
}

QString QLanguageManager::getCurrentText(const QString &id)
{
    if(m_current==NULL)
    {
        return "";
    }
    foreach(tagLanguageItem *it,m_texts)
    {
        if(it->m_id==id)
        {
            return it->m_translate.value(m_current,"");
        }
    }
    return "";
}

void QLanguageManager::save(const QString &projectPath)
{
    QString filename=projectPath+"/language.xml";
    QFile f(filename);
    if(f.open(QFile::WriteOnly))
    {
        f.resize(0);
        QXmlStreamWriter r(&f);
        r.setCodec("UTF-8");
        r.setAutoFormatting(true);

        r.writeStartDocument();
        r.writeStartElement("Languages");
        foreach(QObject* obj,m_languages)
        {
            r.writeStartElement("Language");

            r.writeAttribute("languageName",obj->property("languageName").toString());
            r.writeAttribute("explanation",obj->property("explanation").toString());

            r.writeEndElement();
        }
        r.writeEndElement();
        r.writeEndDocument();
        f.close();
    }
    saveTranslate(projectPath);
}

void QLanguageManager::saveTranslate(const QString &projectPath)
{
    QString filename=projectPath+"/translate.xml";
    QFile f(filename);
    if(f.open(QFile::WriteOnly))
    {
        f.resize(0);
        QXmlStreamWriter r(&f);
        r.setCodec("UTF-8");
        r.setAutoFormatting(true);

        r.writeStartDocument();

        r.writeStartElement("Translate");

        foreach(tagLanguageItem *item,m_texts)
        {
            r.writeStartElement("Item");

            r.writeAttribute("id",item->m_id);
            QMapIterator<QObject*,QString> it(item->m_translate);
            while(it.hasNext())
            {
                it.next();
                r.writeAttribute(it.key()->property("languageName").toString(),it.value());
            }

            r.writeEndElement();
        }

        r.writeEndElement();

        r.writeEndDocument();
        f.close();
    }
}

void QLanguageManager::loadTranslate(const QString &projectPath)
{
    QString filename=projectPath+"/translate.xml";
    QFile f(filename);
    if(f.open(QFile::ReadOnly))
    {
        QXmlStreamReader r(&f);

        while(!r.atEnd())
        {
            if(r.readNext()==QXmlStreamReader::StartElement)
            {
                if(r.name()=="Item")
                {
                    loadTranslageItem(&r);
                }
            }
        }
    }
}

void QLanguageManager::loadTranslageItem(QXmlStreamReader *r)
{

    tagLanguageItem *item;
    QString str;
    item=new tagLanguageItem;
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        str=attribute.name().toString();
        if(str=="id")
        {
            item->m_id=attribute.value().toString();
            if(item->m_id=="")
            {
                delete item;
                r->raiseError("Translate Error!");
                return;
            }
        }
        else
        {
            QObject *obj=getLanguage(str);
            if(obj!=NULL)
            {
                item->m_translate.insert(obj,attribute.value().toString());
            }
        }
    }
    if(item->m_id=="")
    {
        delete item;
        r->raiseError("Translate Error!");
        return;
    }
    else
    {
        m_texts.append(item);
    }
}

void QLanguageManager::load(const QString &projectPath)
{
    release();
    QString filename=projectPath+"/language.xml";
    QFile f(filename);
    if(!f.exists())
    {
        save(projectPath);
        return;
    }

    QString current;
    if(f.open(QFile::ReadOnly))
    {
        QXmlStreamReader r(&f);
        while(!r.atEnd())
        {
            if(r.readNext()==QXmlStreamReader::StartElement)
            {
                if(r.name().toString()=="Language")
                {
                    loadLanguage(&r);
                }
            }
        }
        if(r.hasError())
        {
            qDebug(r.errorString().toLocal8Bit());
            release();
        }
    }
    loadTranslate(projectPath);
    if(current!="")
    {
        setCurrentLanguage(current);
    }
    refreshLanguage();
}

void QLanguageManager::loadLanguage(QXmlStreamReader *r)
{
    QString languageName;
    QString explanation;
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        if(attribute.name().toString()=="languageName")
        {
            languageName=attribute.value().toString();
        }
        else if(attribute.name().toString()=="explanation")
        {
            explanation=attribute.value().toString();
        }
    }
    if(languageName=="")
    {
        r->raiseError("Language Error!");
        return;
    }
    QObject *obj=new QObject;
    obj->setProperty("languageName",languageName);
    obj->setProperty("explanation",explanation);
    addLanguage(obj);
}

void QLanguageManager::release()
{
    m_current=NULL;
    qDeleteAll(m_languages);
    m_languages.clear();
    qDeleteAll(m_texts);
    m_texts.clear();
}

int QLanguageManager::getItemCount()
{
    return m_texts.size();
}

tagLanguageItem* QLanguageManager::getTextItem(int index)
{
    if(index<0 || index>=m_texts.size())
    {
        return NULL;
    }
    else
    {
        return m_texts.at(index);
    }
}

tagLanguageItem *QLanguageManager::getTextItem(const QString &id)
{
    foreach(tagLanguageItem *item,m_texts)
    {
        if(item->m_id==id)
        {
            return item;
        }
    }
    return NULL;
}

void QLanguageManager::addTextItem(tagLanguageItem *item)
{
    foreach(tagLanguageItem *temp,m_texts)
    {
        if(item->m_id==temp->m_id)
        {
            temp->m_translate=item->m_translate;
            emit itemChanged(item);
            return;
        }
    }
    tagLanguageItem *temp=new tagLanguageItem;
    temp->m_id=item->m_id;
    temp->m_translate=item->m_translate;
    m_texts.append(temp);
    emit itemChanged(temp);
}

void QLanguageManager::removeTextItem(const QString &id)
{
    foreach(tagLanguageItem *item,m_texts)
    {
        if(item->m_id==id)
        {
            emit removeItem(id);
            m_texts.removeAll(item);
            delete item;
            emit refreshUi(id);
            return;
        }
    }
}

void QLanguageManager::setText(const QString &language, const QString &id, const QString &text)
{
    tagLanguageItem *item=getTextItem(id);
    if(item!=NULL)
    {
        QObject *lan=getLanguage(language);
        if(item->m_translate.value(lan)!=text)
        {
            item->m_translate.insert(lan,text);
            if(lan==m_current)
            {
                emit refreshUi(id);
            }
        }
    }
}

void QLanguageManager::refreshLanguage()
{
    emit refresh();
}

void QLanguageManager::setLanguageName(QObject *obj, const QString &name)
{
    QString str=obj->property("languageName").toString();
    if(str!=name)
    {
        obj->setProperty("languageName",name);
        emit languageNameChanged(str,name);
        emit refresh();
    }
}
